extern History history;
class CuBe{
    public:
    float size=1.0,scale=0.95;

    Block U  =Block(    0,+size,    0,size*scale);
    Block D  =Block(    0,-size,    0,size*scale);
    Block F  =Block(    0,    0,-size,size*scale);
    Block B  =Block(    0,    0,+size,size*scale);
    Block L  =Block(-size,    0,    0,size*scale);
    Block R  =Block(+size,    0,    0,size*scale);
    Block UFL=Block(-size,+size,-size,size*scale);
    Block UFR=Block(+size,+size,-size,size*scale);
    Block UBL=Block(-size,+size,+size,size*scale);
    Block UBR=Block(+size,+size,+size,size*scale);
    Block DFL=Block(-size,-size,-size,size*scale);
    Block DFR=Block(+size,-size,-size,size*scale);
    Block DBL=Block(-size,-size,+size,size*scale);
    Block DBR=Block(+size,-size,+size,size*scale);
    Block UF =Block(    0,+size,-size,size*scale);
    Block UB =Block(    0,+size,+size,size*scale);
    Block UL =Block(-size,+size,    0,size*scale);
    Block UR =Block(+size,+size,    0,size*scale);
    Block FL =Block(-size,    0,-size,size*scale);
    Block FR =Block(+size,    0,-size,size*scale);
    Block BL =Block(-size,    0,+size,size*scale);
    Block BR =Block(+size,    0,+size,size*scale);
    Block DF =Block(    0,-size,-size,size*scale);
    Block DB =Block(    0,-size,+size,size*scale);
    Block DL =Block(-size,-size,    0,size*scale);
    Block DR =Block(+size,-size,    0,size*scale);
    Block** blocks=new Block*[26]{&U  ,&D  ,&F  ,&B  ,&L  ,&R  ,&UFL,&UFR,&UBL,&UBR,&DFL,&DFR,&DBL,&DBR,&UF ,&UB ,&UL ,&UR ,&FL ,&FR ,&BL ,&BR ,&DF ,&DB ,&DL ,&DR };
    bool isRoting;
    int curStep=0,numStep=fps/5.0;
    char RotShaft;int RotShaftOffset;float RotThetaPerStep;
    CuBe(float size_):size(size_){}
    void draw(SDL_Renderer* renderer,SDL_Surface* ScSurface,Camara camara){
        U  .draw( renderer, ScSurface, camara);
        D  .draw( renderer, ScSurface, camara);
        F  .draw( renderer, ScSurface, camara);
        B  .draw( renderer, ScSurface, camara);
        L  .draw( renderer, ScSurface, camara);
        R  .draw( renderer, ScSurface, camara);
        UFL.draw( renderer, ScSurface, camara);
        UFR.draw( renderer, ScSurface, camara);
        UBL.draw( renderer, ScSurface, camara);
        UBR.draw( renderer, ScSurface, camara);
        DFL.draw( renderer, ScSurface, camara);
        DFR.draw( renderer, ScSurface, camara);
        DBL.draw( renderer, ScSurface, camara);
        DBR.draw( renderer, ScSurface, camara);
        UF .draw( renderer, ScSurface, camara);
        UB .draw( renderer, ScSurface, camara);
        UL .draw( renderer, ScSurface, camara);
        UR .draw( renderer, ScSurface, camara);
        FL .draw( renderer, ScSurface, camara);
        FR .draw( renderer, ScSurface, camara);
        BL .draw( renderer, ScSurface, camara);
        BR .draw( renderer, ScSurface, camara);
        DF .draw( renderer, ScSurface, camara);
        DB .draw( renderer, ScSurface, camara);
        DL .draw( renderer, ScSurface, camara);
        DR .draw( renderer, ScSurface, camara);
    }
    void click(int x_,int y_,int mousedown,Camara camara){
        Vertex tmp;tmp.csz=0.06;
        tmp.scx=x_;tmp.scy=y_;
        int flag=0;//视线射线法
        for(float z_=0.06;z_<20.0;z_+=0.01){
            tmp.scz=1/z_;
            if(tmp.ifInScreenSpace(camara))
                tmp.CamaraToWorld(camara);
            if (!(tmp.x<-size*3.0/2.0||tmp.x>size*3.0/2.0||
                  tmp.y<-size*3.0/2.0||tmp.y>size*3.0/2.0||
                  tmp.z<-size*3.0/2.0||tmp.z>size*3.0/2.0)){
                flag=1;break;
            }
        }if(flag==0)return;//↓得到命中坐标
        float x=tmp.x,y=tmp.y,z=tmp.z;
        float absx=x<0?-x:x,absy=y<0?-y:y,absz=z<0?-z:z;
        char L=0,C=0;//判断影响层
        if(absx>absy&&absx>absz&&x>=0.0)L='R';
        if(absx>absy&&absx>absz&&x< 0.0)L='L';
        if(absy>absx&&absy>absz&&y>=0.0)L='U';
        if(absy>absx&&absy>absz&&y< 0.0)L='D';
        if(absz>absy&&absz>absx&&z< 0.0)L='F';
        if(absz>absy&&absz>absx&&z>=0.0)L='B';
        C=mousedown==1?'1': mousedown==2?'2': mousedown==3?'3':'0';
        history.push(L,C);//编码压栈
    }
    void updateRotDate(){
        if (isRoting||history.isTaskAllClear())return;
        //↑正在旋转或无代办
        history.getter();history.next();//滚动代办任务
        if (History_::Ret[0]==0)return;
        int rtct=1;//直角Rotate计数,↓解码转动方向
        rtct*=History_::Ret[1]=='3'?-1:History_::Ret[1]-'0';
        switch (History_::Ret[0]){//解码命令到转轴信息
            case 'U':rtct*=-1;RotShaft='y';RotShaftOffset= 1;break;
            case 'D':rtct*=+1;RotShaft='y';RotShaftOffset=-1;break;
            case 'R':rtct*=-1;RotShaft='x';RotShaftOffset= 1;break;
            case 'L':rtct*=+1;RotShaft='x';RotShaftOffset=-1;break;
            case 'F':rtct*=+1;RotShaft='z';RotShaftOffset=-1;break;
            case 'B':rtct*=-1;RotShaft='z';RotShaftOffset= 1;break;
            case 'M':rtct*=+1;RotShaft='x';RotShaftOffset= 0;break;
            case 'E':rtct*=+1;RotShaft='y';RotShaftOffset= 0;break;
            case 'S':rtct*=+1;RotShaft='z';RotShaftOffset= 0;break;
            default:break;
        }//↓步旋量
        RotThetaPerStep=90.0*rtct/numStep;
        isRoting=true;//魔方状态更新
    }
    void update(){
        updateRotDate();if(!isRoting)return;
        curStep+=1;//↑更新当前转动信息和魔方状态,↓旋转完毕状态更新
        if (curStep>=numStep){curStep=0;isRoting=false;}
        for (int i=0;i<26;i++){
            int BP[3]{//遍历小块,获得其逻辑位置
                blocks[i]->x>size/2?1:blocks[i]->x<-size/2?-1:0,
                blocks[i]->y>size/2?1:blocks[i]->y<-size/2?-1:0,
                blocks[i]->z>size/2?1:blocks[i]->z<-size/2?-1:0};
            if((RotShaft=='x'&&RotShaftOffset==BP[0])
             ||(RotShaft=='y'&&RotShaftOffset==BP[1])
             ||(RotShaft=='z'&&RotShaftOffset==BP[2])){
                blocks[i]->operateBlock(0,0,RotShaft,RotThetaPerStep);
            }//↑处于转动层的进行旋转
            else{continue;}
        }
    }
};

